package com.stb.server;

import java.util.UUID;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;

import com.google.inject.Inject;
import com.stb.client.remote.UserService;
import com.stb.server.dao.UserDAO;
import com.stb.server.mail.MailSender;
import com.stb.server.url.URLEncoder;
import com.stb.server.util.BCrypt;
import com.stb.shared.domain.User;

public class UserServiceImpl implements UserService, RequestInjectedService {
	
	private static final Logger logger = Logger.getLogger(UserServiceImpl.class.getName());
	
	@Inject private UserDAO userDAO;
	@Inject private MailSender mailSender;
	@Inject private URLEncoder urlEncoder;

	private HttpServletRequest request;
	
	@Override
	public String logon(String email, String password) throws IllegalArgumentException {
		User user = this.userDAO.get(email);
		if (user != null) {
			if (!user.isActive()) {
				throw new IllegalArgumentException("User is not active");
			}
			String storedPassword = user.getPassword();
			if (BCrypt.checkpw(password, storedPassword)) {
				return UUID.randomUUID().toString();
			}
		}
		throw new IllegalArgumentException("Incorrect username/password");
	}

	@Override
	public void register(String email, String password) throws IllegalArgumentException {
		
		logger.info("Registering user: " + email);
		User existingUser = this.userDAO.get(email);
		if (existingUser != null ) {
			throw new IllegalArgumentException("User already registered");
		}
		User user = new User.Builder()
			.email(email)
			.password(BCrypt.hashpw(password, BCrypt.gensalt()))
			.build();					
		this.userDAO.save(user);
		this.sendActivationEmail(email);
	}

	private void sendActivationEmail(String email) {
		String url = getBaseUrl();
		url = this.urlEncoder.encode(url, "activate=true", "email=" + email);
		this.mailSender.send(email, "Welcome to Yaggle", "Please click on link to activate your account\n\n" + url);
	}

	private String getBaseUrl() {
		if ((request.getServerPort() == 80) || (request.getServerPort() == 443)) {
			return request.getScheme() + "://" + request.getServerName() + request.getContextPath();
		} else {
			return request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() + request.getContextPath();
		}
	}

	@Override
	public void activate(String urlParams) throws IllegalArgumentException {
		String url = this.getBaseUrl() + "#" + urlParams;
		if (this.urlEncoder.validate(url) == false) {
			throw new IllegalArgumentException("Invalid url");
		}
		this.userDAO.activate(this.urlEncoder.getParam(urlParams, "email"));
	}

	@Override
	public void setRequest(HttpServletRequest request) {
		this.request = request;
	}
}
